package me.lovatcat.springboot.demo.web;

import me.lovetcat.common.constant.Resp;
import me.lovetcat.common.dto.FieldErrorDto;
import me.lovetcat.common.dto.RespDto;
import me.lovetcat.common.util.WebUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.util.List;

/**
 * 全局异常处理类
 * @author acat on 2017-01-12 08:14
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 未捕获异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public RespDto exceptionHandler(Exception e){
        LOG.error(e.getMessage(), e);
        return RespDto.fail(Resp.Code.FAIL_SYS_EXCEPTION.value(), Resp.Code.FAIL_SYS_EXCEPTION.msg());
    }

    /**
     * 控制层请求参数转换异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public RespDto paramsTypeErrorHandler(MethodArgumentTypeMismatchException e){
        return RespDto.fail(Resp.Code.FAIL_PARAM_TYPE.value(), Resp.Code.FAIL_PARAM_TYPE.msg());
    }

    /**
     * 请求方式不正确(需要post，使用get方式请求)
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public RespDto requestMethodNotSupportedHandler(HttpRequestMethodNotSupportedException e){
        return RespDto.fail(Resp.Code.FAIL_REQUEST_METHOD.value(), Resp.Code.FAIL_REQUEST_METHOD.msg());
    }

    /**
     * 用来处理校验入参异常
     * @param e
     * @return
     */
//    @ExceptionHandler(value = BindException.class)
//    @ResponseBody
//    public RespDto<FieldErrorDto> paramsValidHandler(BindException e){
//        List<FieldErrorDto> fieldErrorDtos = WebUtil.setFieldValidErrorMsgs(e.getFieldErrors());
//        return RespDto.fail_valid(fieldErrorDtos);
//    }

    /**
     * Spring Boot中, 当用户访问了一个不存在的链接时,Spring 默认会将页面重定向到/error上, 而不会抛出异常
     * 配置 spring.resources.add-mappings=false、spring.mvc.throw-exception-if-no-handler-found=true来取消该默认行为
     * 但是如果配置了会影响到swagger api文档工具的使用:
     *      会处理所有controller中没有处理的请求，这样就不能用/swagger-ui.html来访问文档了
     * 本例中不使用该方法
     *
     * 未找到请求资源异常
     * @param e
     * @return
     */
//    @ExceptionHandler(value = NoHandlerFoundException.class)
//    @ResponseStatus(code = HttpStatus.NOT_FOUND)
//    @ResponseBody
//    public RespObj notFoundHandler(ServletException e){
//        return RespObj.fail(Resp.Code.FAIL_404.value(), Resp.Code.FAIL_404.msg());
//    }

}
